﻿#ifndef atom_h__2013_7_26__20_30
#define atom_h__2013_7_26__20_30

//
#define LIMIT_32BIT_INTEGER(INTT) static_assert(sizeof(INTT)==4,"argument type must be 32bit integer")
#define LIMIT_64BIT_INTEGER(INTT) static_assert(sizeof(INTT)==8 && std::is_integral<INTT>::value,"argument type must be 64bit integer")

//原子操作
namespace df
{
	//自增
	template<typename IntT>
	inline static IntT AtomInc(volatile IntT * var)
	{
		LIMIT_32BIT_INTEGER(IntT);
		DF_ASSERT(var != nullptr);
#ifdef _MSC_VER
		return _InterlockedIncrement((long volatile *)(var));
#elif WIN32
		return InterlockedIncrement((long volatile *)(var));
#else
		return __sync_add_and_fetch(var, 1);
#endif
	}

	//自减
	template<typename IntT>
	inline static IntT AtomDec(volatile IntT * var)
	{
		LIMIT_32BIT_INTEGER(IntT);
		DF_ASSERT(var != nullptr);
#ifdef _MSC_VER
		return _InterlockedDecrement((long volatile *)(var));
#elif WIN32
		return InterlockedDecrement((long volatile *)(var));
#else
		return __sync_add_and_fetch(var, -1);
#endif
	}

	//加一个值
	template<typename IntT>
	inline static IntT AtomAdd(volatile IntT * var, IntT value)
	{
		LIMIT_32BIT_INTEGER(IntT);
		DF_ASSERT(var != nullptr);
#ifdef _MSC_VER
		return _InterlockedExchangeAdd((long volatile *)(var), (long)value);
#elif WIN32
        return InterlockedExchangeAdd((long volatile *)(var), (long)value);
#else
		return __sync_fetch_and_add(var, value);
#endif
	}


	//*******************************************
	// Summary : 如果var与compare相等,则将value赋值给var
	// Parameter - volatile IntT * var : 目标变量
	// Parameter - IntT compare : 待比较的数
	// Parameter - IntT value : 待赋值
	// Returns - IntT : 原var的值(未赋值前)
	//*******************************************
	template<typename IntT>
	inline static IntT AtomCompareExchange(volatile IntT * var, IntT compare, IntT value)
	{
		LIMIT_32BIT_INTEGER(IntT);
		DF_ASSERT(var != nullptr);
#ifdef _MSC_VER
		return (IntT)_InterlockedCompareExchange((long volatile *)(var), (long)value, (long)compare);
#else
		return __sync_val_compare_and_swap (var, compare,value);
#endif
	}

	inline static void * AtomCompareExchangePtr(volatile void * var, void * compare, void * val)
	{
		DF_ASSERT(var != nullptr);
#ifdef _MSC_VER
		return _InterlockedCompareExchangePointer((void *volatile *)var, val, compare);
#else
		return __sync_val_compare_and_swap((void**)var, compare, val);
#endif
	}


	/*
	template<typename IntT>
	inline static IntT AtomAdd64( volatile IntT * var, IntT value)
	{
	LIMIT_64BIT_INTEGER(INTT)
	return _InterlockedExchangeAdd64(var,value);
	}*/


	//赋值
	template<typename IntT>
	inline static IntT AtomSet(volatile IntT * var, IntT value)
	{
		LIMIT_32BIT_INTEGER(IntT);
		DF_ASSERT(var != nullptr);
#ifdef _MSC_VER
		return _InterlockedExchange((long volatile *)(var), (long)value);
#else
		return __sync_lock_test_and_set(var, value);
#endif
	}

	//取值
	template<typename IntT>
	inline static IntT AtomGet(volatile IntT * var)
	{
		LIMIT_32BIT_INTEGER(IntT);
		DF_ASSERT(var != nullptr);
#ifdef _MSC_VER
		return _InterlockedExchangeAdd((long volatile *)(var), 0);
#else
		return __sync_fetch_and_add(var, 0);
#endif
	}


}

#endif // atom_h__2013_7_26__20_30
